#!/bin/bash

BMC_LOG=$1  # BMC一键信息收集日志文件路径, eg: /home/xxx.tar.gz
CHIP_FREQ=289
MLX_DRIVER_VERSION="5.8-1.1.2.1"
MLX_LINK_WIDTH=16
PF_LOG_BAR_SIZE=8
PCI_WR_ORDERING="force_relax(1)"
IP_STATUS=false
CUR_PATH=$(dirname $(readlink -f $0))
CUR_HOST=$(hostname)
LOG=${CUR_PATH}/check_env-${CUR_HOST}.log

check_cpu()
{
    echo "=========check cpu=========="
    cpu_model=`lscpu |grep "Model name" |cut -d':' -f2 |sed 's/^[[:blank:]]*//'`
    echo "[INFO] cpu model: ${cpu_model}."
    cores=`cat /proc/cpuinfo |grep processor |wc -l`
    echo "[INFO] cpu cores: ${cores}."
    cpu_freq=`dmidecode -t4 |grep "Current Speed" |awk '{print $3}' |head -1`
    echo "[INFO] cpu frequency: ${cpu_freq} MHz."
    cpu_mode=`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor`
    echo "[INFO] cpu run mode: ${cpu_mode}."
    threads_per_core=`lscpu |grep "per core" |awk '{print $NF}'`
    if [ ${threads_per_core} -eq 2 ];then
        echo "[ERROR] Hyperthreading enabled."
    fi
    cpu_min_freq=`cat /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq |sort -r |tail -1 |cut -b -3`
    if [ ${cpu_min_freq} -lt ${CHIP_FREQ} ];then
        echo "[ERROR] CPU frequency reduction."
    fi
    numa_nodes=`lscpu |grep "NUMA node(s)" |awk '{print $3}'`
    echo "[INFO] numa nodes: ${numa_nodes}."
}

check_mem()
{
    echo ""
    echo "=========check mem=========="
    cores=`cat /proc/cpuinfo |grep processor |wc -l`
    if [ $cores -eq 320 ];then
        num_dimm=`dmidecode -t memory |grep "Manufacturer:" |grep "NO DIMM" |wc -l`
        if [ $num_dimm -ne 0 ];then
            echo "[ERROR] Memory Not Best Insertion Method."
        fi
    else
        num_dimm_odd=`dmidecode -t memory |grep "Type:" |grep -v Error |awk 'NR%2==1' |grep DDR |wc -l`
        num_dimm_even=`dmidecode -t memory |grep "Type:" |grep -v Error |awk 'NR%2==0' |grep DDR |wc -l`
        if [ $num_dimm_odd -ne 16 ] || [ $num_dimm_even -ne 0 ];then
            echo "[ERROR] Memory Not Best Insertion Method."
        fi
    fi

    dmidecode -t memory |grep "Manufacturer:" |grep -v "NO DIMM" > tmp.txt
    if [ `uniq -c tmp.txt |wc -l` -ne 1 ];then
        echo "[ERROR] Inconsistent memory Manufacturer."
        uniq -c tmp.txt
    else
        manu=`uniq -c tmp.txt |awk '{print $3}' |head -1`
        echo "[INFO] memory manufacturer: ${manu}."
    fi

    dmidecode -t memory |grep "Speed" |grep -v "Configured" |grep -v Unknown > tmp.txt
    if [ `uniq -c tmp.txt |wc -l` -ne 1 ];then
        echo "[ERROR] Inconsistent memory Speed."
        uniq -c tmp.txt
    else
        mem_Speed=`uniq -c tmp.txt |awk '{print $3,$4}' |head -1`
        echo "[INFO] memory raw Speed: ${mem_Speed}."
    fi
    
    dmidecode -t memory |grep "Configured Memory Speed" |grep -v Unknown > tmp.txt
    if [ `uniq -c tmp.txt |wc -l` -ne 1 ];then
        echo "[ERROR] Inconsistent Configured memory Speed."
        uniq -c tmp.txt
    else
        config_mem_Speed=`uniq -c tmp.txt |awk '{print $5,$6}' |head -1`
        echo "[INFO] memory run Speed: ${config_mem_Speed}."
    fi

    dmidecode -t memory |grep "Type: DDR" > tmp.txt
    if [ `uniq -c tmp.txt |wc -l` -ne 1 ];then
        echo "[ERROR] Inconsistent DDR type."
        uniq -c tmp.txt
    else
        ddr_type=`uniq -c tmp.txt |awk '{print $3}' |head -1`
        echo "[INFO] memory type: ${ddr_type}."
    fi

    dmidecode -t memory |grep "Size" |egrep 'GB|MB' > tmp.txt
    if [ `uniq -c tmp.txt |wc -l` -ne 1 ];then
        echo "[ERROR] Inconsistent memory capacity."
        uniq -c tmp.txt
    else
        mem_cap=`uniq -c tmp.txt |awk '{print $3,$4}' |head -1`
        echo "[INFO] memory capacity: ${mem_cap}."
    fi    
}

check_disk()
{
    echo ""
    echo "=========check disk========="
    
    lsblk |grep nvme > /dev/null 2>&1
    if [ $? -eq 0 ];then
       echo "[INFO] nvme in use."
    fi
    disk_type=`lsblk -d -o name,rota |egrep 'nvme|sd' |awk '{print $2}' |awk '{sum+=$1} END {print sum}'`
    if [ ${disk_type} -eq 0 ];then
        echo "[INFO] disk type: SSD."
    else
        echo "[ERROR] disk type: HDD."
    fi

}

check_net()
{
    echo ""
    echo "=========check net=========="
    echo "[INFO] card model: " 
    lspci |grep -i Mellanox |cut -d':' -f3 |sed 's/^[[:blank:]]*//'
    
    which ibdev2netdev > /dev/null 2>&1
    if [ $? -ne 0 ];then
        echo "[ERROR] ibdev2netdev command not found."
        return
    fi
    port_list=`ibdev2netdev |grep -i up |awk '{print $5}'`
    if [ $? -ne 0 ];then
        echo "[ERROR] no active port."
        return
    fi
    
    for port_name in ${port_list}
    do
        echo ""
        echo "[INFO] port name: ${port_name},`ethtool $port_name |grep Speed`"
        driver_ver=`ofed_info -n`
        if [ $driver_ver != $MLX_DRIVER_VERSION ];then
            echo "[ERROR] mlx driver version is not ${MLX_DRIVER_VERSION}"
        fi
        
        firmware_ver=`ethtool -i $port_name | grep -i firmware-version | awk '{print $2}'`
        #echo "[INFO] card firmware version: ${firmware_ver}"
        bdf=`ethtool -i $port_name | grep -i bus-info |awk '{print $2}'`
        pcie_linkcap=`lspci -vvvv -s $bdf |grep -i "LnkCap:" |sed -E 's/.*x([0-9]+).*/\1/'`
        #echo "[INFO] PCIe slot link capability: ${pcie_linkcap}"
        card_linkwidth=`lspci -vvvv -s $bdf |grep -i "LnkSta:" |sed -E 's/.*x([0-9]+).*/\1/'`
        if [ $card_linkwidth -ne $MLX_LINK_WIDTH ];then
            echo "[ERROR] current link width is x${card_linkwidth}, not x${MLX_LINK_WIDTH}."
        fi
        ip=`ip addr |grep ${port_name} |grep inet |awk '{print $2}' |head -1`
        if [ ! -z $ip ];then
            IP_STATUS=true
        fi
    done
    
    if [ $IP_STATUS == "false" ];then
        echo "[ERROR] mlxcard not config ip."
    fi

    which mlxconfig > /dev/null 2>&1
    if [ $? -ne 0 ];then
        echo "[ERROR] mlxconfig command not found."
        return
    fi
    which mst > /dev/null 2>&1
    if [ $? -ne 0 ];then
        echo "[ERROR] mst command not found."
        return
    else
        mst start > /dev/null
    fi
    
    for dev in `mst status |grep mst |awk '{print $1}'`
    do
        bar_size=`mlxconfig -d $dev q |grep PF_LOG_BAR_SIZE |awk '{print $2}'`
        if [ $bar_size -ne $PF_LOG_BAR_SIZE ];then
            echo "[ERROR] PF_LOG_BAR_SIZE is not equal to ${PF_LOG_BAR_SIZE}"
        fi
        
        wr_ordering=`mlxconfig -d $dev q |grep PCI_WR_ORDERING |awk '{print $2}'`
        if [ $wr_ordering != $PCI_WR_ORDERING ];then
            echo "[ERROR] PCI_WR_ORDERING is not ${PCI_WR_ORDERING}"
        fi
    done
    
    which ibstatus > /dev/null 2>&1
    if [ $? -ne 0 ];then
        echo "[ERROR] ibstatus command not found."
    else
        echo "[INFO] card mode(IB or RoCE): "
        ibstatus |grep link_layer |awk '{print $2}'
    fi
    
    if [ ! -f /etc/init.d/cx.sh ];then
        echo "[ERROR] file /etc/init.d/cx.sh not exist."
    else
        cat /etc/rc.local |grep "/etc/init.d/cx.sh" > /dev/null 2>&1
        if [ $? -ne 0 ];then
            echo "[ERROR] '/etc/init.d/cx.sh' should be written to file '/etc/rc.local'." 
        fi
    fi
}

check_bios()
{
    echo ""
    echo "=========check bios========="
    bios_ver=`dmidecode -s bios-version`
    echo "[INFO] bios version: ${bios_ver}"
}

check_os()
{
    echo ""
    echo "=========check os==========="
    os_ver=`cat /etc/*rele* |head -1`
    echo "[INFO] os version: ${os_ver}."
    kernel_ver=`uname -r`
    echo "[INFO] kernel version: ${kernel_ver}."

    firewalld_status=`systemctl status firewalld.service |grep Active |awk '{print $2}'`
    if [ $firewalld_status != "inactive" ];then
        echo "[ERROR] firewalld service active."
    fi
    
    if [ `ulimit -s` != 'unlimited' ] || [ `ulimit -l` != 'unlimited' ] || [ `ulimit -u` != '1000000' ] || [ `ulimit -n` != '1000000' ];then
        echo "[ERROR] incorrect limit configuration, please modify file '/etc/security/limits.conf'."
        ulimit -a
    fi
    
    if [ `systemctl get-default` != 'multi-user.target' ];then
        echo "[ERROR] incorrect display mode, please execute command 'systemctl set-default multi-user.target'."
    fi
    
    if [ `getenforce` != 'Disabled' ];then
        echo "[ERROR] incorrect SELinux status, please execute command 'sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' /etc/selinux/config && setenforce 0 && reboot'."
    fi
    
    echo "[INFO] numa_balancing: `sysctl -n kernel.numa_balancing`" 
    echo "[INFO] tuned mode:`tuned-adm active |cut -d':' -f2`" 
    echo "[INFO] irqbalance service: `systemctl status irqbalance |grep Active |awk '{print $2}'`" 
    echo "[INFO] transparent hugepage status: `cat /sys/kernel/mm/transparent_hugepage/enabled |cut -d'[' -f2 |cut -d']' -f1`" 
    echo "[INFO] transparent hugepage defrag: `cat /sys/kernel/mm/transparent_hugepage/defrag |cut -d'[' -f2 |cut -d']' -f1`" 
    echo "[INFO] hugepages total: `cat /proc/meminfo |grep HugePages_Total |awk '{print $2}'`" 
}

check_exagear()
{
    echo ""
    echo "=========check exagear==========="
    which exagear > /dev/null 2>&1
    if [ $? -ne 0 ];then
        echo "[INFO] exagear not installed."
        return
    fi
    arch=`exagear -- arch`
    if [ $? -ne 0 ] || [ ${arch} != 'x86_64' ];then
        echo "[ERROR] exagear environment abnormal."
        return
    fi
    
    exagear_binfmt32_status=`systemctl status exagear-x86_32-binfmt.service |grep Active |awk '{print $2}'`
    if [ $exagear_binfmt32_status == "inactive" ];then
        echo "[ERROR] exagear-x86_32-binfmt service inactive."
    fi

    exagear_binfmt64_status=`systemctl status exagear-x86_64-binfmt.service |grep Active |awk '{print $2}'`
    if [ $exagear_binfmt64_status == "inactive" ];then
        echo "[ERROR] exagear-x86_64-binfmt service inactive."
    fi

    exagear_opt32_status=`systemctl status exagear-x86_32-opt.service |grep Active |awk '{print $2}'`
    if [ $exagear_opt32_status == "inactive" ];then
        echo "[ERROR] exagear-x86_32-opt service inactive."
    fi

    exagear_opt64_status=`systemctl status exagear-x86_64-opt.service |grep Active |awk '{print $2}'`
    if [ $exagear_opt64_status == "inactive" ];then
        echo "[ERROR] exagear-x86_64-opt service inactive."
    fi
    
    for vpath in `find /opt/exagear/images -name vpaths-list`
    do
        cat ${vpath} |grep "/var/lib/sss/" > /dev/null  2>&1
        if [ $? -ne 0 ];then
            echo "[INFO] AD domain user path [/var/lib/sss/] not in vpaths-list."
        fi
        
        for obj in `sed -n '/\/var\/lib\/dbus\//,$p' ${vpath} |grep -v dbus`
        do
            if [ ! -e $obj ] || [ ! -e /opt/exagear/images/centos-7-x86_64/$obj ];then
                echo "[ERROR] exagear path [$obj] mounting failed."
            else
                echo "[INFO] current mounted path [$obj]."
            fi
        done
    done
}

check_bmc_log()
{
    echo ""
    echo "=========check bmc log==========="
    if [ -z ${BMC_LOG} ] || [ ! -f ${BMC_LOG} ];then
        return
    fi
    tar -zxvf ${BMC_LOG} > /dev/null 2>&1
    bios_json=`find ./ -name currentvalue.json`
    cd `dirname ${bios_json}`
    PeformanceProfile=`python -c "import json;data = json.load(open('currentvalue.json', 'r'));print(data['BenchMarkSelection'])"`
    PowerPolicy=`python -c "import json;data = json.load(open('currentvalue.json', 'r'));print(data['PowerPolicy'])"`
    SMT2=`python -c "import json;data = json.load(open('currentvalue.json', 'r'));print(data['SMT2En'])"`
    CPUPrefetch=`python -c "import json;data = json.load(open('currentvalue.json', 'r'));print(data['CPUPrefetchConfig'])"`
    RefreshRate=`python -c "import json;data = json.load(open('currentvalue.json', 'r'));print(data['DdrRefreshRate'])"`
    if [[ ${PeformanceProfile} != 'HPC' ]] || [[ ${PowerPolicy} != 'Performance' ]] || [[ ${SMT2} != 'Disabled' ]] || [[ ${CPUPrefetch} != 'Enabled' ]] || [[ ${RefreshRate} != '1x Mode' ]];then
        echo [ERROR] uncorrect bios config.
    fi
    echo [INFO] PeformanceProfile: ${PeformanceProfile}, PowerPolicy: ${PowerPolicy}, SMT2: ${SMT2}, CPUPrefetch: ${CPUPrefetch}, RefreshRate: ${RefreshRate}

    cd `dirname ${BMC_LOG}`/dump_info/AppDump/sensor
    fan_speed=`cat sensor_info.txt |grep RPM |awk '{print $7}' |head -1 |cut -d'.' -f1`
    echo "[INFO] current fanspeed is ${fan_speed}."
}

echo "----------------environment check------------------------"
echo ""  > ${LOG} 2>&1
check_cpu >> ${LOG} 2>&1
check_mem >> ${LOG} 2>&1
check_disk >> ${LOG} 2>&1
check_net >> ${LOG} 2>&1
check_bios >> ${LOG} 2>&1
check_os >> ${LOG} 2>&1
check_exagear >> ${LOG} 2>&1
check_bmc_log >> ${LOG} 2>&1

cat ${LOG}

##全局变量
#--------------------------------#
date

for i in `rpm -qa`
do
for ((j=0;j<20;j++))
do
echo -n -e "$i\t"
done
echo ""
done

echo "----------------------------BeGin---------------------------"
date
echo "ip:"
ip a|grep inet|grep -v inet6
ps -ef|grep java

echo "----------------CPU Info------------------------"
lscpu

echo "----------------CPU run mode------------------------"
for i in `cat /sys/devices/system/cpu/cpu[0-9]*/cpufreq/scaling_governor`
do
echo -n -e "$i\t"
done

echo "----------------cpu frequency------------------------"
for i in `cat /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq`
do
echo -n -e "$i\t"
done


echo "----------------hardware environment------------------------"
echo "uname:"
cat /etc/os-release
uname -a;
ulimit -a;
free -h;
echo "meminfo:"
cat /proc/meminfo;
echo "lsblk:"
lsblk;
echo "dmidecode:"
dmidecode
wait

echo "----------------PROC STATEMENT------------------------"
who -u
echo "cpu info dec:"

echo "filesystem info dec:"
cat /proc/filesystems


echo "fstab info dec:"
cat /etc/fstab

echo "----------------netcard environment------------------------"
for net0 in `ls /sys/class/net/`
do
    if [[ $net0 == vir* ]] || [[ $net0 == lo ]];then
        continue
    fi
    echo "netcard is $net0"
    ethtool $net0;
    echo "=========================================================="
    echo "ethtool -a dec："
    ethtool -a $net0;
    echo "ethtool -c dec："
    ethtool -c $net0;
    echo "----------------------------------------------------------"
    echo "ethtool -n dec："
    ethtool -n $net0;
    echo "----------------------------------------------------------"
    echo "ethtool -g dec："
    ethtool -g $net0;
    echo "ethtool -i dec："
    ethtool -i $net0;
    echo "----------------------------------------------------------"
    echo "ethtool -k dec："
    ethtool -k $net0;
    echo "ethtool -l dec："
    ethtool -l $net0;
    echo "----------------------------------------------------------"
    echo "ethtool -t dec："
    ethtool -T $net0;

    echo "----------------------------------------------------------"
    echo "--show-fec dec："
    ethtool --show-fec $net0;
    echo "--show-eee dec："
    ethtool --show-eee $net0;
    echo "=========================================================="
done

PF_LOG_BAR_SIZE=`mlxconfig q |grep PF_LOG_BAR_SIZE |awk '{print $2}'`
echo "[INFO] PF_LOG_BAR_SIZE: ${PF_LOG_BAR_SIZE}"
PCI_WR_ORDERING=`mlxconfig q |grep PCI_WR_ORDERING |awk '{print $2}'`
echo "[INFO] PCI_WR_ORDERING: ${PCI_WR_ORDERING}"

echo "--------------------BIOS--------------------------"
echo ""
bios_ver=`dmidecode -s bios-version`
echo "[INFO] bios version: ${bios_ver}"


echo "--------------------VG display--------------------------"
vgdisplay;
lvdisplay;
echo "---------------software environment---------------------"
echo "the boot option is dec:"
cat /proc/cmdline;

echo "----------------DEVICE environment----------------------"
for device in `lsblk|grep disk|awk  '{print $1}'`
do
echo "the Device is: $device"
echo "the nr_requests is:"
cat /sys/block/${device}/queue/nr_requests;
echo "the queue_depth is:"
cat /sys/block/${device}/device/queue_depth;
echo "the scheduler is:"
cat /sys/block/${device}/queue/scheduler
echo "---------xxxx-----------"
done

echo "------------------OS environment----------------------"
sysctl -a|grep -v sched_domain|grep -v ipv4|grep -v ipv6|sort;
sysctl -a|grep ipv4|sort;
sysctl -a|grep ipv6|sort;
sysctl -a|grep sched_domain|sort -t '.' -k 3.4,3.5 -n
sysctl -a

echo "------------------Exagear Parameter----------------------"
cat /etc/exagear-x86_64.conf
cat /etc/exagear-x86_32.conf

echo "----------------------END-----------------------------"